package com.kurumi.service.impl;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.kurumi.config.MyConfig;
import com.kurumi.mapper.BaseInfoMapper;
import com.kurumi.mapper.MedicalRecordImageMapper;
import com.kurumi.mapper.MedicalRecordMapper;
import com.kurumi.mapper.MedicalRecordScanMapper;
import com.kurumi.mapper.ScanImageMapper;
import com.kurumi.pojo.MedicalRecord;
import com.kurumi.pojo.MedicalRecordImage;
import com.kurumi.pojo.MedicalRecordTrace;
import com.kurumi.pojo.ScanImage;
import com.kurumi.pojo.upload.MedicalResource;
import com.kurumi.pojo.upload.MedicalResourcePic;
import com.kurumi.pojo.upload.ScanFile;
import com.kurumi.pojo.upload.UploadScan;
import com.kurumi.pojo.upload.UploadScanFile;
import com.kurumi.query.MedicalRecordQuery;
import com.kurumi.query.MedicalRecordScanQuery;
import com.kurumi.query.UploadScanQuery;
import com.kurumi.service.MedicalRecordScanService;
import com.kurumi.util.GuidUtil;
import com.kurumi.util.StringUtil;

@Service
public class MedicalRecordScanServiceImpl implements MedicalRecordScanService {

	@Autowired
	private MyConfig myConfig;
	
	@Autowired
	private BaseInfoMapper baseInfoMapper;
	
	@Autowired
	private MedicalRecordMapper medicalRecordMapper;
	
	@Autowired
	private ScanImageMapper scanImageMapper;
	
	@Autowired
	private MedicalRecordImageMapper medicalRecordImageMapper;
	
	@Autowired
	private MedicalRecordScanMapper medicalRecordScanMapper;
	
	
	@Override
	public List<Map<String, Object>> getMedicalRecordOfScan(MedicalRecordScanQuery query) {
		// TODO Auto-generated method stub
		return medicalRecordScanMapper.getMedicalRecordOfScan(query);
	}

	@Override
	public int getMedicalRecordCountOfScan(MedicalRecordScanQuery query) {
		// TODO Auto-generated method stub
		return medicalRecordScanMapper.getMedicalRecordCountOfScan(query);
	}

	@Transactional(propagation=Propagation.REQUIRED)
	@SuppressWarnings("unchecked")
	@Override
	public void scanImagesUpload(String visitGuid, MultipartFile[] uploadImages) throws IllegalStateException, IOException {
		// TODO Auto-generated method stub
		Subject subject=SecurityUtils.getSubject();
		Session session = subject.getSession();
		Map<String, Object> currentUser = (Map<String, Object>)session.getAttribute("currentUser");
		String userCode =(String)currentUser.get("user_code");
		String userName = (String)currentUser.get("user_name");
		List<ScanImage> scanImages = new ArrayList<ScanImage>();
		for (MultipartFile uploadImage : uploadImages) {
			ScanImage scanImage = new ScanImage();
			//文件原名称
			String originalFilename=uploadImage.getOriginalFilename();
			//文件流Hash（100位）
			String hashStr = new StringBuffer(GuidUtil.get36SystemHash(new String(uploadImage.getBytes()))).reverse().toString();
			

			//获取文件后缀名
			String fileSuffixes = originalFilename.substring(originalFilename.lastIndexOf(".")+1);
			long fileSize = uploadImage.getSize();
			String fileSizeHashStr = GuidUtil.get36SystemHash(fileSize);
			
			//文件Hash
			String fileHash = new StringBuffer(hashStr).append(fileSizeHashStr).toString();
			String localPath = GuidUtil.getLocalPath(hashStr);
			
			String newFileName = hashStr.substring(8)+fileSizeHashStr.substring(0, 5);
			scanImage.setFileHash(fileHash);
			scanImage.setFileName(newFileName+"."+fileSuffixes);
			scanImage.setOriginalFileName(originalFilename);
			scanImage.setFileType(fileSuffixes);
			scanImages.add(scanImage);
			//文件保存路径
			String filePath = myConfig.getImageRecourcePath() + localPath;
			File destFile = new File(filePath,newFileName+"."+fileSuffixes);
			if(!destFile.exists()){
				File destDir = new File(filePath);
				if(!destDir.exists()){
					destDir.mkdirs();
				}
				uploadImage.transferTo(destFile);
			}
		}
		for (ScanImage scanImage : scanImages) {
			if(scanImageMapper.selectByPrimaryKey(scanImage.getFileHash()) == null){
				scanImage.setCreateUserId(userCode);
				scanImage.setCreateUserName(userName);
				System.err.println(scanImage.getFileName().length());
				System.err.println(scanImage.getFileHash().length());
				scanImageMapper.insert(scanImage);
			}
			int imageIndex = 0;
			if(medicalRecordImageMapper.getCountByFileHashAndVisitGuid(scanImage.getFileHash(), visitGuid)==0){
				MedicalRecordImage medicalRecordImage = new MedicalRecordImage();
				medicalRecordImage.setFileHash(scanImage.getFileHash());
				medicalRecordImage.setVisitGuid(visitGuid);
				medicalRecordImage.setCreateUserId(userCode);
				medicalRecordImage.setCreateUserName(userName);
				medicalRecordImage.setLastUserId(userCode);
				medicalRecordImage.setLastUserName(userName);
				imageIndex++;
				medicalRecordImage.setSortIndex(imageIndex);
				medicalRecordImageMapper.insert(medicalRecordImage);
			}
		}
		
		List<Map<String,Object>>  treatmentTraceTypes = baseInfoMapper.getTraceTypeByCode(MedicalRecordTrace.VISIT_SCAN);
		if(treatmentTraceTypes.isEmpty()){
			throw new RuntimeException(String.format("treatmentTraceTypes %s为空", MedicalRecordTrace.VISIT_SCAN_NAME));
		}
		MedicalRecordTrace scanTrace = new MedicalRecordTrace();
		
		scanTrace.setVisitGuid(visitGuid);
		
		scanTrace.setCreateUserId(userCode);
		scanTrace.setCreateUserName(userName);
		scanTrace.setTraceTypeCode((String)treatmentTraceTypes.get(0).get("code"));
		scanTrace.setTraceTypeName((String)treatmentTraceTypes.get(0).get("name"));
		int count = medicalRecordMapper.insertMedicalRecordTrace(scanTrace);
		if(count != 1){
			throw new RuntimeException(String.format("创建medicalRecordTrace(%s)失败", visitGuid));
		}
	}

	@Override
	public List<Map<String, Object>> getImageFilesByVisitGuid(String visitGuid) {
		// TODO Auto-generated method stub
		return medicalRecordImageMapper.getImageFilesByVisitGuid(visitGuid);
	}

	@Override
	public List<Map<String, Object>> getImageFileByFileHash(String fileHash) {
		// TODO Auto-generated method stub
		return medicalRecordImageMapper.getImageFileByFileHash(fileHash);
	}

	@Transactional(propagation=Propagation.REQUIRED)
	@Override
	public int imagePagination(String visitGuid, String fileHash, String newPageTypeCode) {
		// TODO Auto-generated method stub
		MedicalRecordImage medicalRecordImage =medicalRecordImageMapper.selectByVisitGuidAndFileHash(visitGuid, fileHash);
		if(medicalRecordImage !=null){
			Subject subject=SecurityUtils.getSubject();
			
			Session session = subject.getSession();
			Map<String, Object> currentUser = (Map<String, Object>)session.getAttribute("currentUser");
			String userCode =(String)currentUser.get("user_code");
			String userName = (String)currentUser.get("user_name");
			medicalRecordImage.setMrPageTypeCode(newPageTypeCode);
			medicalRecordImage.setFirsPigeonholedDateTime(new Date());
			medicalRecordImage.setLastUserId(userCode);
			medicalRecordImage.setLastUserName(userName);
			medicalRecordImage.setLastDateTime(new Date());
			return medicalRecordImageMapper.imagePagination(medicalRecordImage);
		}
		return 0;
	}

	@Override
	public List<Map<String, Object>> getPaginationCountByVisitGuid(String visitGuid) {
		// TODO Auto-generated method stub
		return medicalRecordImageMapper.getPaginationCountByVisitGuid(visitGuid);
	}

	@Override
	public int getUnPaginationImageCountByVisitGuid(String visitGuid) {
		// TODO Auto-generated method stub
		return medicalRecordImageMapper.getUnPaginationImageCountByVisitGuid(visitGuid);
	}

	@Transactional(propagation=Propagation.REQUIRED)
	@Override
	public int imagePaginationFinish(String visitGuid) {
		// TODO Auto-generated method stub
		int unPaginationImageCount = medicalRecordImageMapper.getUnPaginationImageCountByVisitGuid(visitGuid);
		if(unPaginationImageCount != 0){
			return -2;
		}
		List<Map<String,Object>> treatmentTraceTypes = baseInfoMapper.getTraceTypeByCode(MedicalRecordTrace.VISIT_PAGINATION);
		if(treatmentTraceTypes.size() == 0){
			return -2;
		}
		if(medicalRecordMapper.getMeditalRecordTraceCount(visitGuid, MedicalRecordTrace.VISIT_PAGINATION) > 0){
			return 2;
		}
		MedicalRecordTrace medicalRecordTrace = new MedicalRecordTrace();
		medicalRecordTrace.setVisitGuid(visitGuid);
		Subject subject=SecurityUtils.getSubject();
		Session session = subject.getSession();
		Map<String, Object> currentUser = (Map<String, Object>)session.getAttribute("currentUser");
		medicalRecordTrace.setCreateUserId((String)currentUser.get("user_code"));
		medicalRecordTrace.setCreateUserName((String)currentUser.get("user_name"));
		medicalRecordTrace.setTraceTypeCode((String)treatmentTraceTypes.get(0).get("code"));
		medicalRecordTrace.setTraceTypeName((String)treatmentTraceTypes.get(0).get("name"));
		
		return medicalRecordMapper.insertMedicalRecordTrace(medicalRecordTrace);
	}

	@Override
	public List<Map<String, Object>> getImageFilesByVisitGuidAndPrinterTypeCode(String visitGuid,
			String printerTypeCode) {
		// TODO Auto-generated method stub
		return medicalRecordImageMapper.getImageFilesByVisitGuidAndPrinterTypeCode(visitGuid, printerTypeCode);
	}

	@Override
	public List<Map<String, Object>> getMedicalRecordOfScanSend(MedicalRecordQuery medicalRecordQuery) {
		// TODO Auto-generated method stub
		return medicalRecordScanMapper.getMedicalRecordOfScanSend(medicalRecordQuery);
	}

	@Override
	public int getMedicalRecordCountOfScanSend(MedicalRecordQuery medicalRecordQuery) {
		// TODO Auto-generated method stub
		return medicalRecordScanMapper.getMedicalRecordCountOfScanSend(medicalRecordQuery);
	}
	
	@Override
	public List<Map<String, Object>> getMedicalRecordScanSend(MedicalRecordQuery medicalRecordQuery) {
		// TODO Auto-generated method stub
		return medicalRecordScanMapper.getMedicalRecordScanSendData(medicalRecordQuery);
	}

	@Override
	public int getMedicalRecordCountScanSend(MedicalRecordQuery medicalRecordQuery) {
		// TODO Auto-generated method stub
		return medicalRecordScanMapper.getMedicalRecordCountScanSendData(medicalRecordQuery);
	}


	@Transactional(propagation=Propagation.REQUIRED)
	@Override
	public int thirdScanUpload(Map<String, UploadScan> uploadScanMap) {
		// TODO Auto-generated method stub
		for (String folderName : uploadScanMap.keySet()) {
			UploadScan uploadScan = uploadScanMap.get(folderName);
			medicalRecordScanMapper.insertUploadScan(uploadScan);
			/*save uploadScan*/
			for (ScanFile scanFile : uploadScan.getScanFiles()) {
				medicalRecordScanMapper.insertScanFile(scanFile);
				/*save scanFile*/
				UploadScanFile uploadScanFile=new UploadScanFile();
				uploadScanFile.setFileHash(scanFile.getFileHash());
				uploadScanFile.setOriginalFileName(scanFile.getOriginalName());
				uploadScanFile.setUploadScanId(uploadScan.getId());
				medicalRecordScanMapper.insertUploadScanFile(uploadScanFile);
				/*save uploadScanFile*/
				/*MedicalResource medicalResource = new MedicalResource();
				medicalResource.setFirstLevelMedicalId(uploadScan.getFirstLevelMedicalGuid());
				medicalResource.setMedicalResourceTypeId(1);
				medicalResource.setCreateDate(new Date());
				save medicalResource
				MedicalResourcePic medicalResourcePic = new MedicalResourcePic();
				medicalResourcePic.setFileHash(uploadScanFile.getFileHash());
				medicalResourcePic.setMedicalResourceId(medicalResource.getId());
				save medicalResource*/
			}
			
		}
		return 1;
	}

	@Override
	public List<Map<String, Object>> getUploadScanByQuery(UploadScanQuery query) {
		// TODO Auto-generated method stub
		return medicalRecordScanMapper.getUploadScanByQuery(query);
	}

	@Override
	public int getUploadScanCountByQuery(UploadScanQuery query) {
		// TODO Auto-generated method stub
		return medicalRecordScanMapper.getUploadScanCountByQuery(query);
	}

	@Transactional(propagation=Propagation.REQUIRED)
	@Override
	public int addMedicalRecordRelevance(MedicalRecord medicalRecord, Integer uploadScanId) {
		// TODO Auto-generated method stub
		int count = 0;
		medicalRecord.setVisitGuid(StringUtil.getId());
		count = medicalRecordMapper.insert(medicalRecord);
		if(count < 0){
			return 0;
		}
		List<Map<String,Object>> treatmentTraceTypes = baseInfoMapper.getTraceTypeByCode(MedicalRecordTrace.VISIT_INIT);
		if(treatmentTraceTypes.size() == 0){
			return 0;
		}
		
		MedicalRecordTrace medicalRecordTrace = new MedicalRecordTrace();
		
		medicalRecordTrace.setVisitGuid(medicalRecord.getVisitGuid());
		Subject subject=SecurityUtils.getSubject();
		Session session = subject.getSession();
		Map<String, Object> currentUser = (Map<String, Object>)session.getAttribute("currentUser");
		medicalRecordTrace.setCreateUserId((String)currentUser.get("user_code"));
		medicalRecordTrace.setCreateUserName((String)currentUser.get("user_name"));
		medicalRecordTrace.setTraceTypeCode((String)treatmentTraceTypes.get(0).get("code"));
		medicalRecordTrace.setTraceTypeName((String)treatmentTraceTypes.get(0).get("name"));
		count = medicalRecordMapper.insertMedicalRecordTrace(medicalRecordTrace);
		List<String> fileHashs=medicalRecordScanMapper.getFileHashByUploadScanId(uploadScanId);
		
		MedicalResource medicalResource=null;
		MedicalResourcePic medicalResourcePic=null;
		for (String fileHash : fileHashs) {
			medicalResource=new MedicalResource();
			medicalResource.setFirstLevelMedicalId(medicalRecord.getVisitGuid());
			medicalResource.setMedicalResourceTypeId(1);
			medicalResource.setCreateDate(new Date());
			medicalRecordScanMapper.insertMedicalResource(medicalResource);
			
			medicalResourcePic=new MedicalResourcePic();
			medicalResourcePic.setFileHash(fileHash);
			medicalResourcePic.setMedicalResourceId(medicalResource.getId());
			medicalRecordScanMapper.insertMedicalResourcePic(medicalResourcePic);
		}
		UploadScan uploadScan=new UploadScan();
		uploadScan.setId(uploadScanId);
		uploadScan.setFirstLevelMedicalGuid(medicalRecord.getVisitGuid());
		//uploadScan.setStatus(2);
		count = medicalRecordScanMapper.updateUploadScanRelevance(uploadScan);
		
		return count;
	}

	@Override
	public List<Map<String, Object>> getMedResourceByFirstLevelGuid(String firstLevelGuid) {
		// TODO Auto-generated method stub
		return medicalRecordScanMapper.getMedResourceByFirstLevelGuid(firstLevelGuid);
	}

	@Transactional(propagation=Propagation.REQUIRED)
	@Override
	public int medicalRecordRelevance(String mrId, Integer visitNumber, Integer uploadScanId) {
		// TODO Auto-generated method stub
		int count = 0;
		List<String> fileHashs=medicalRecordScanMapper.getFileHashByUploadScanId(uploadScanId);
		List<String> visitGuids =medicalRecordMapper.getVisitGuidByMrIdAndVisitNumber( mrId, visitNumber);
		MedicalResource medicalResource=null;
		MedicalResourcePic medicalResourcePic=null;
		for (String fileHash : fileHashs) {
			medicalResource=new MedicalResource();
			medicalResource.setFirstLevelMedicalId(visitGuids.get(0));
			medicalResource.setMedicalResourceTypeId(1);
			medicalResource.setCreateDate(new Date());
			medicalRecordScanMapper.insertMedicalResource(medicalResource);
			
			medicalResourcePic=new MedicalResourcePic();
			medicalResourcePic.setFileHash(fileHash);
			medicalResourcePic.setMedicalResourceId(medicalResource.getId());
			medicalRecordScanMapper.insertMedicalResourcePic(medicalResourcePic);
		}
		UploadScan uploadScan=new UploadScan();
		uploadScan.setId(uploadScanId);
		uploadScan.setFirstLevelMedicalGuid(visitGuids.get(0));
		//uploadScan.setStatus(2);
		count = medicalRecordScanMapper.updateUploadScanRelevance(uploadScan);
		return count;
	}

	@Override
	public List<Map<String, Object>> getPaginationScanFilesByFirstGuidAndPagination(String firstGuid,
			String pagination) {
		// TODO Auto-generated method stub
		String unpagination=null;
		if("1".equals(pagination)){
			unpagination=pagination;
			pagination=null;
		}else{
			unpagination=null;
		}
		
		List<Map<String,Object>> mapList = medicalRecordScanMapper.getPaginationScanFilesByFirstGuidAndPagination(firstGuid,pagination,unpagination);
		
		for (Map<String, Object> map : mapList) {
			//没有编页过的 按照原图片名称排序 
			if(map.get("originalFileName")!=null){
				String originalFileName = (String)map.get("originalFileName");
				int length = originalFileName.indexOf(".");
				String indexSort = originalFileName.substring(0, length);
				map.put("sortIndex", indexSort);
			}
			
			//已经编页过的 按照主键排序
			if(map.get("mr_page_type_id")!=null){
				int pageTypeId = (int)map.get("mr_page_type_id");
				List<Map<String,Object>> mrPageTypes = medicalRecordScanMapper.getMrPageTypeById(pageTypeId);
				if(!mrPageTypes.isEmpty()){
					map.put("dataIndex", mrPageTypes.get(0).get("sort_code"));
				}
				
			}
		}
		return mapList;
	}

	@Override
	public List<Map<String, Object>> getMrPageTypes() {
		// TODO Auto-generated method stub
		return medicalRecordScanMapper.getMrPageTypes();
	}

	@Override
	public List<Map<String, Object>> getMrPageTypesOfPaginationCountByFirstGuid(String firstGuid) {
		// TODO Auto-generated method stub
		return medicalRecordScanMapper.getMrPageTypesOfPaginationCountByFirstGuid(firstGuid);
	}

	@Override
	public int getScanFilePaginationCount(String firstGuid, String unPagination) {
		// TODO Auto-generated method stub
		return medicalRecordScanMapper.getPaginationFileCount(firstGuid, unPagination);
	}

	@Transactional(propagation=Propagation.REQUIRED)
	@Override
	public int paginationMedrecordImage(String firstGuid, String fileHash, Integer mrPageTypeId) {
		// TODO Auto-generated method stub
		
		MedicalResource medicalResource = medicalRecordScanMapper.getMedicalResourceByFirstGuidAndFileHash(fileHash, firstGuid);
		
		if(medicalResource !=null){
			medicalResource.setMrPageType(mrPageTypeId);
			medicalResource.setCreateDate(new Date());
			medicalResource.setStatus(1);
			medicalRecordScanMapper.updateMedicalResourceById(medicalResource);
			return 1;
		}
		return 0;
	}

	@Override
	public List<Map<String, Object>> getMrPageTypesOfPaginationCountByFirstGuidAndMrPageTypes(String firstGuid,
			List<Integer> mrPageTypes) {
		// TODO Auto-generated method stub
		return medicalRecordScanMapper.getMrPageTypesOfPaginationCountByFirstGuidAndMrPageId(firstGuid, mrPageTypes);
		
	}

	@Transactional(propagation=Propagation.REQUIRED)
	@Override
	public int removeMedRecordImage(String firstGuid, String fileHash) {
		// TODO Auto-generated method stub
		int result = 0;
		try{
			MedicalResourcePic medicalResourcePic = medicalRecordScanMapper.getMedicalResourcePicByFirstGuidAndFileHash(firstGuid, fileHash);
		    result += medicalRecordScanMapper.deleteMedicalResourcePicById(medicalResourcePic.getId());
		    result += medicalRecordScanMapper.deleteMedicalResourceById(medicalResourcePic.getMedicalResourceId());
		}catch(Exception ex){
			result = 0;
			ex.printStackTrace();
		}
		
		return result;
	}

	@Transactional(propagation=Propagation.REQUIRED)
	@Override
	public void updateScanFilrOriginalName(String fileHash, String preOriginalName) {
		// TODO Auto-generated method stub
		ScanFile scanFile = medicalRecordScanMapper.getScanFileByFileHash(fileHash);
		String fileType = scanFile.getFileType();
		scanFile.setOriginalName(preOriginalName+"."+fileType);
		medicalRecordScanMapper.updateScanFileByFileHash(scanFile);
	}

}
